home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Topik / Topik - Disk 02 - Fonts and CLI Commands (19xx)(Topik Public Domain)(PD)[a][WB].zip / Topik - Disk 02 - Fonts and CLI Commands (19xx)(Topik Public Domain)(PD)[a][WB].adf / Source / memtrace.asm < prev    next >
Assembly Source File  |  1989-04-20  |  10KB  |  291 lines

  1. * ===========================     MemTrace     ===========================
  2. *
  3. * Monitors calls to AllocMem and FreeMem for tracking down wayward memory.
  4. * Uses two buffers to store the size, address, and requesting task.  Each
  5. * buffer area "wraps around" when filled; data may be lost, but no harm
  6. * will be done.
  7. *
  8. * Two commands are accepted from the input stream:
  9. *    'B' ==> prints out the buffer (after switching buffers)
  10. *    'E' ==> exits from the program.
  11. *
  12. * Written by William S. Hawes (1987)
  13. * ========================================================================
  14.  
  15.          SECTION  MemTrace,CODE
  16.          INCLUDE  "exec/types.i"
  17.          INCLUDE  "exec/nodes.i"
  18.          INCLUDE  "exec/libraries.i"
  19.  
  20. * Macro to call a library function (assumes library pointer is in A6)
  21. CALLSYS  MACRO    * FunctionName
  22.          CALLLIB  _LVO\1
  23.          ENDM
  24.  
  25. * Macro to define an external library entry point (offset)
  26. XLIB     MACRO    * FunctionName
  27.          XREF     _LVO\1
  28.          ENDM
  29.  
  30.          XREF     _AbsExecBase
  31.          XREF     _printf
  32.  
  33.          XDEF     _DOSBase
  34.          XDEF     _stdout
  35.  
  36.          XLIB     AllocMem
  37.          XLIB     CloseLibrary
  38.          XLIB     Disable
  39.          XLIB     Enable
  40.          XLIB     FindTask
  41.          XLIB     FreeMem
  42.          XLIB     OpenLibrary
  43.          XLIB     SetFunction
  44.  
  45.          XLIB     Input
  46.          XLIB     Output
  47.          XLIB     Read
  48.  
  49. STACKBUF EQU      32
  50. MAXCNT   EQU      128                     ; maximum number of entries
  51.  
  52. start:   movea.l  _AbsExecBase,a6
  53.          lea      -STACKBUF(sp),sp
  54.  
  55.          lea      DOSlib(pc),a1
  56.          moveq    #0,d0
  57.          CALLSYS  OpenLibrary
  58.          move.l   d0,d6
  59.          move.l   d0,_DOSBase
  60.          beq      Exit                 ; error??
  61.  
  62.          ; Allocate the buffer areas (before patching the functions!)
  63.  
  64.          move.l   #MAXCNT*16,d0        ; MAXCNT 16-byte entries
  65.          move.l   d0,Save2             ; store offset
  66.          add.l    d0,d0                ; two buffers ...
  67.          move.l   #(1<<16)!(1<<0),d1   ; MEMF_PUBLIC!MEMF_CLEAR
  68.          CALLSYS  AllocMem
  69.          move.l   d0,Save1             ; first buffer
  70.          add.l    d0,Save2             ; second buffer
  71.          move.l   d0,Buffer            ; current buffer
  72.          beq      CloseDOS             ; error ...
  73.  
  74.          bsr      Zap                  ; zap the functions ...
  75.  
  76.          ; Get the input and output streams
  77.  
  78.          exg      d6,a6
  79.          CALLSYS  Input
  80.          move.l   d0,d4
  81.          CALLSYS  Output
  82.          move.l   d0,_stdout
  83.          exg      d6,a6
  84.  
  85.          ; Wait for a character: 'B' or 'E'
  86.  
  87. 1$:      move.l   d4,d1                ; input filehandle
  88.          move.l   sp,d2                ; buffer area
  89.          moveq    #STACKBUF,d3         ; buffer size
  90.          exg      d6,a6
  91.          CALLSYS  Read
  92.          exg      d6,a6
  93.          tst.l    d0                   ; get one?
  94.          beq.s    1$                   ; no
  95.  
  96.          move.b   (sp),d0              ; the character ...
  97.          bclr     #5,d0                ; uppercase
  98.          subi.b   #'B',d0              ; 'Begin'?
  99.          beq.s    2$                   ; yes
  100.          subq.b   #'E'-'B',d0          ; 'End'?
  101.          beq.s    10$                  ; yes
  102.          bra.s    1$                   ; ignore
  103.  
  104.          ; Swap the buffer areas so the one we're printing doesn't get
  105.          ; overwritten.
  106.  
  107. 2$:      movea.l  Save1,a0             ; first buffer area
  108.          movea.l  Save2,a1             ; second buffer area
  109.          cmpa.l   Buffer,a0            ; using first buffer?
  110.          beq.s    4$                   ; yes
  111. 3$:      exg      a0,a1                ; no ... swap pointers
  112.  
  113. 4$:      clr.l    (a1)                 ; reset count in new buffer
  114.          move.l   a1,Buffer            ; switch buffers
  115.          move.l   (a0),d2              ; number of entries
  116.          lea      16(a0),a2            ; start of save frame array
  117.  
  118.          ; Label the columns ... 
  119.  
  120.          pea      label(pc)
  121.          jsr      _printf
  122.          addq.l   #4,sp
  123.          bra.s    7$                   ; jump in ...
  124.  
  125.          ; Loop through the captured size/task/address items.  First, we
  126.          ; select the format string.
  127.  
  128. 5$:      lea      afmt(pc),a0          ; AllocMem format
  129.          tst.l    0(a2)                ; allocation?
  130.          beq.s    6$                   ; yes
  131.          lea      ffmt(pc),a0          ; FreeMem format
  132.  
  133. 6$:      move.l   4(a2),-(sp)          ; size
  134.          move.l   12(a2),-(sp)         ; address
  135.          move.l   8(a2),-(sp)          ; task ID
  136.          move.l   a0,-(sp)             ; format string
  137.          jsr      _printf
  138.          lea      16(sp),sp
  139.          lea      16(a2),a2            ; advance array pointer
  140. 7$:      dbra     d2,5$                ; loop back
  141.          bra      1$
  142.  
  143.          ; Restore the library functions and exit ...
  144.  
  145. 10$:     bsr      UnZap                ; unpatch the entries
  146.  
  147.          movea.l  Save1,a1             ; buffer
  148.          move.l   #MAXCNT*32,d0        ; total length
  149.          CALLSYS  FreeMem
  150.  
  151.          ; Close the DOS library 
  152.  
  153. CloseDOS:
  154.          movea.l  d6,a1
  155.          CALLSYS  CloseLibrary
  156.  
  157. Exit:
  158.          lea      STACKBUF(sp),sp
  159.          rts
  160.  
  161.          ; Zap the EXEC library AllocMem and FreeMem functions ...
  162.  
  163. Zap:     CALLSYS  Disable              ; no interruptions, please
  164.          move.w   #_LVOAllocMem,a0     ; offset
  165.          movea.l  a6,a1                ; library
  166.          move.l   #AllocChk,d0         ; new (monitor) function
  167.          CALLSYS  SetFunction
  168.          move.l   d0,AllocFun          ; save original value
  169.  
  170.          move.w   #_LVOFreeMem,a0
  171.          movea.l  a6,a1
  172.          move.l   #FreeChk,d0          ; monitor function
  173.          CALLSYS  SetFunction
  174.          move.l   d0,FreeFun
  175.          CALLSYS  Enable
  176.          rts
  177.  
  178.          ; Restore the library entry points ...
  179.  
  180. UnZap:   CALLSYS  Disable
  181.          move.w   #_LVOAllocMem,a0
  182.          movea.l  a6,a1
  183.          move.l   AllocFun,d0
  184.          CALLSYS  SetFunction
  185.  
  186.          move.w   #_LVOFreeMem,a0
  187.          movea.l  a6,a1
  188.          move.l   FreeFun,d0
  189.          CALLSYS  SetFunction
  190.          CALLSYS  Enable
  191.          rts
  192.  
  193.          ; Static storage area ...
  194.  
  195. _stdout  dc.l     0
  196. _DOSBase dc.l     0
  197. AllocFun dc.l     0                    ; real AllocMem function
  198. FreeFun  dc.l     0                    ; real FreeMem
  199. Buffer   dc.l     0                    ; current buffer
  200. Save1    dc.l     0                    ; first buffer
  201. Save2    dc.l     0                    ; second buffer
  202.  
  203. label    dc.b     '           AllocMem     FreeMem  ',10
  204.          dc.b     'Task ID   Addr  Size   Addr  Size',10,0
  205. afmt     dc.b     '%6lx: %6lx  %4ld             ',10,0
  206. ffmt     dc.b     '%6lx:              %6lx  %4ld',10,0
  207. DOSlib   dc.b     'dos.library',0
  208.          CNOP     0,2
  209.  
  210.          ; AllocMem monitor function.  This code will be executed by
  211.          ; any function that calls AllocMem.
  212.  
  213. AllocChk:
  214.          movem.l  d2/a2,-(sp)
  215.          movem.l  d0/d1,-(sp)
  216.  
  217.          ; Disable interrupts while we check where to put the data ...
  218.  
  219.          CALLSYS  Disable
  220.          movea.l  Buffer,a2            ; current buffer
  221.          cmpi.l   #MAXCNT-1,(a2)       ; count too big?
  222.          bcs.s    1$                   ; no
  223.          clr.l    (a2)                 ; reset
  224. 1$:      move.l   (a2),d2              ; count
  225.          lsl.l    #4,d2                ; scale for 16 bytes
  226.          addq.l   #1,(a2)              ; increment count
  227.          lea      16(a2),a2            ; first save frame
  228.          CALLSYS  Enable
  229.  
  230.          ; See who asked for it ...
  231.  
  232.          suba.l   a1,a1                ; see
  233.          CALLSYS  FindTask
  234.          movea.l  d0,a0
  235.          movem.l  (sp)+,d0/d1          ; restore size and attributes
  236.  
  237.          ; Special (conditional) code to trap certain references ...
  238.  
  239.          IFD      SPECIAL
  240.          cmp.l    #20,d0               ; 20 bytes?
  241.          bne.s    2$                   ; no 
  242.          trap     #11                  ; gotcha!
  243. 2$:
  244.          ENDC
  245.  
  246.          lea      0(a2,d2.l),a2        ; start of frame
  247.          clr.l    (a2)+                ; clear flag
  248.          move.l   d0,(a2)+             ; save size
  249.          move.l   a0,(a2)+             ; save task
  250.          movea.l  AllocFun,a0
  251.          jsr      (a0)                 ; call AllocMem
  252.          move.l   d0,(a2)              ; save address
  253.          movem.l  (sp)+,d2/a2
  254.          rts
  255.  
  256.          ; Monitor FreeMem activity ...
  257.  
  258. FreeChk:
  259.          movem.l  d2/a2,-(sp)
  260.          movem.l  d0/a1,-(sp)          ; save size and address
  261.  
  262.          CALLSYS  Disable
  263.          movea.l  Buffer,a2            ; buffer area
  264.          cmpi.l   #MAXCNT-1,(a2)       ; count too big?
  265.          bcs.s    1$                   ; no
  266.          clr.l    (a2)                 ; reset it
  267. 1$:      move.l   (a2),d2              ; current item count
  268.          lsl.l    #4,d2                ; scale for 16 bytes
  269.          addq.l   #1,(a2)              ; increment count
  270.          lea      16(a2),a2            ; first save frame
  271.          CALLSYS  Enable
  272.  
  273.          ; See who asked for it ...
  274.  
  275.          suba.l   a1,a1
  276.          CALLSYS  FindTask
  277.          movea.l  d0,a0                ; requesting task
  278.  
  279.          movem.l  (sp)+,d0/a1
  280.          lea      0(a2,d2.l),a2        ; start of frame
  281.          move.l   #-1,(a2)+            ; set flag
  282.          move.l   d0,(a2)+             ; save size
  283.          move.l   a0,(a2)+             ; save task
  284.          move.l   a1,(a2)              ; save address
  285.          movea.l  FreeFun,a0
  286.          jsr      (a0)                 ; call FreeMem
  287.          movem.l  (sp)+,d2/a2
  288.          rts
  289.  
  290.          END
  291.